#I Import and Initialize
import  sys, os
import pygame
import random
from data import *
from sprites import *
from scenes import *
from level import *

def RelRect(actor, camera):
    return Rect(actor.rect.x-camera.rect.x, actor.rect.y-camera.rect.y, actor.rect.w, actor.rect.h)

class Camera(object):
    def __init__(self, player, width, level):
        self.player         = player
        self.rect           = pygame.display.get_surface().get_rect()
        self.world          = Rect(0, 0, width, 480)
        self.rect.center    = self.player.rect.center
        self.level          = level
        
    def update(self):
        if self.rect.right <= (self.level.get_rect().right * 32):
            if self.player.rect.centerx > self.rect.centerx+64:
                self.rect.centerx = self.player.rect.centerx-64
            if self.player.rect.left < self.rect.left:
                self.player.rect.left = self.rect.left
            self.rect.clamp_ip(self.world)
        
    def draw_sprites(self, surf, sprites):
        for s in sprites:
            if s.rect.colliderect(self.rect):
                surf.blit(s.image, RelRect(s, self))
                
class Game(object):
    
    def __init__(self, screen, lvl=1):
        
        self.screen      = screen
        self.birdUps     = loadImage("bird-ups.png")
        
        self.background  = loadImage("background.png")
        
        #A Action onderverdeeld in ALTER
        
        #A Assign
        self.sprites           = pygame.sprite.OrderedUpdates()
        self.playerSprites     = pygame.sprite.OrderedUpdates()
        self.ballSprites       = pygame.sprite.OrderedUpdates()
        self.cannonSprites     = pygame.sprite.OrderedUpdates()
        self.cannon2Sprites    = pygame.sprite.OrderedUpdates()
        self.explosionSprites  = pygame.sprite.OrderedUpdates()
        self.cannonBallSprites = pygame.sprite.OrderedUpdates()
        self.bricksSprites     = pygame.sprite.OrderedUpdates()
        self.grassSprites      = pygame.sprite.OrderedUpdates()
        self.cloudSprites      = pygame.sprite.OrderedUpdates()
        self.finishSprites     = pygame.sprite.OrderedUpdates()
        self.finishlineSprites = pygame.sprite.OrderedUpdates()
        
        Player.groups       = self.sprites, self.playerSprites
        PlayerDef.groups    = self.sprites, self.ballSprites
        Cannon.groups       = self.sprites, self.cannonSprites
        Cannon2.groups      = self.sprites, self.cannon2Sprites
        Explosion.groups    = self.sprites, self.explosionSprites
        CannonDef.groups    = self.sprites, self.cannonBallSprites
        Brick.groups        = self.sprites, self.bricksSprites
        Grass.groups        = self.sprites, self.grassSprites
        Cloud.groups        = self.sprites, self.cloudSprites
        Finish.groups       = self.sprites, self.finishSprites
        FinishLine.groups   = self.sprites, self.finishlineSprites
        
        self.events      = None
        self.player      = Player(10, 60, self.events)
        self.level       = Level(self.player, lvl)
        self.camera      = Camera(self.player, (self.screen.get_rect().width * 32), self.level)
        
        self.score       = 0
        self.lives       = 3
        self.time        = 400
        self.lvl         = lvl
        self.font        = pygame.font.Font(filepath("fonts/font1.ttf"), 16)
        self.speed       = [4, 4]
        self.bgspeed     = [-1,0]
        self.white       = 255, 255, 255
        self.clock       = pygame.time.Clock()
        self.keepGoing   = True
        self.frame       = 0
        
        self.main_loop()
        
    def get_lvl_score(self, lvl):
        try:
            return int(open(filepath("..\saves\lvl%d.sav" % lvl)).read())
        except:
            return 0
    
    def save_lvl(self, lvl, score):
        if self.get_lvl_score(lvl) <= score:
            open(filepath("..\saves\lvl%d.sav" % lvl), "w").write(str(score))
        
    def gameover_screen(self):
        cutscene(self.screen, ["Game Over"])
        self.keepGoing = False
        
    def finish_screen(self):
        self.save_lvl(self.lvl, self.score)
        cutscene(self.screen, ["Level Complete"], self)
        self.next_level()
 
    def draw_stats(self):
        firstLine = 16
        secondLine = 35
        
        lives = self.lives
        if lives < 0:
            lives = 0
        
        ren = self.font.render("Score: %05d" % self.score, 1, (255, 255, 255))
        self.screen.blit(ren, (608, firstLine))
               
        ren = self.font.render("Level: %0d" % self.lvl, 1, (255, 255, 255))
        self.screen.blit(ren, (608, secondLine))
        
        ren = self.font.render("x%d" % lives, 1, (255, 255, 255))
        self.screen.blit(ren, (478, firstLine))
               
        ren = self.font.render("FPS: %d" % self.clock.get_fps(), 1, (255, 255, 255))
        self.screen.blit(ren, (478, secondLine))
        
        self.screen.blit(self.birdUps, (420, firstLine))
    
    def space_pressed(self):
        PlayerDef((self.player.rect.centerx - 30), self.player.rect.centery)
        #self.ballSprites.add(self.ball)
    
    def go_horizontal(self, x):
        self.player.x_velocity = x
    
    def go_vertical(self, y):
        self.player.y_velocity = y

    def blink(self, sprite):
        frame = 0
       
        if frame <= 50:
            frame += 1
        else:
            frame = 0
            
    def next_level(self):
        self.kill_sprites()
        self.lvl += 1
        self.player      = Player(10, 60, self.events)
        self.level       = Level(self.player, self.lvl)
        self.camera      = Camera(self.player, (self.screen.get_rect().width * 32), self.level)
        
    
    def kill_sprites(self):
        for s in self.sprites:
            pygame.sprite.Sprite.kill(s)
            
        #L Loop
    def main_loop(self):    
        while self.keepGoing:
            #T Timer (framerate)
            self.events = pygame.event.get()
            self.player.events = self.events
            self.frame += 1
            self.clock.tick(90)

            self.player.collide(self.grassSprites)
            self.player.collide(self.bricksSprites)
            
            for f in self.finishlineSprites:
                if self.player.rect.colliderect(f.rect):
                    self.finish_screen()
            
            for b in self.ballSprites:
                if pygame.sprite.spritecollideany(b, self.grassSprites):
                    b.kill()
                if pygame.sprite.spritecollideany(b, self.bricksSprites):
                    b.kill()
                    
            for c in self.cannonBallSprites:
                if self.player.rect.colliderect(c.rect):
                    c.kill()
                    self.score += 50
                if c.rect.left < self.camera.rect.left:
                    c.kill()
                if c.rect.right > self.camera.rect.right:
                    c.kill()
                if c.rect.top < self.camera.rect.top:
                    c.kill()
                if pygame.sprite.spritecollideany(c, self.grassSprites):
                    c.kill()
                if pygame.sprite.spritecollideany(c, self.bricksSprites):
                    c.kill() 
                
            for c in self.cannonSprites:
                if self.player.rect.colliderect(c.rect):
                    c.kill()
                    if self.lives <= 1:
                        self.score = -1;
                    else:
                        self.lives -=1
                if pygame.sprite.spritecollideany(c, self.ballSprites):
                    c.kill()
                    Explosion(c.rect.center)
                    self.score += 10
                if c.rect.left < self.camera.rect.left:
                    c.kill()
            
            for c in self.cannon2Sprites:
                if self.player.rect.colliderect(c.rect):
                    c.kill()
                    if self.lives <= 1:
                        self.score = -1;
                    else:
                        self.lives -=1
                if pygame.sprite.spritecollideany(c, self.ballSprites):
                    c.kill()
                    Explosion(c.rect.center)
                    self.score += 10
                if c.rect.left < self.camera.rect.left:
                    c.kill()
            
            if self.score < 0 and self.lives <= 1:
                self.gameover_screen()
            elif self.score < 0:
                self.lives -= 1
                self.score = 0
                
            #R refresh
            self.camera.update()
            self.playerSprites.update()
            self.ballSprites.update()
            self.cannonSprites.update()
            self.cannon2Sprites.update()
            self.cannonBallSprites.update()
            self.explosionSprites.update()
            
            
            self.screen.fill(self.white)
            self.screen.blit(self.background, self.background.get_rect())
            
            for event in self.events:
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        self.keepGoing = False
            
            self.camera.draw_sprites(self.screen, self.sprites)

            self.draw_stats()
            
            pygame.display.flip()
